/*

DA4
*/

#define F_CPU 8000000
#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#define byte char
int main ()
{
	char green, blue, red; // counter to modify various PWM duty cycles
	char arrR[5] = {0x01,0x02,0x03,0x01,0x02};
	char arrG[5] = {0x03,0x02,0x01,0x03,0x02};
	char arrB[5] = {0x02,0x03,0x02,0x01,0x03};
	
	TCCR0A = 0xA1;
	TCCR0B = 0x04; // Phase Correct PWM, inverted, N = 256
	TCCR1A = 0xA1;
	TCCR1B = 0x01; // Phase Correct PWM, inverted, no prescaler
	TCCR2A = 0xA1;
	TCCR2B = 0x05; // Phase Correct PWM, inverted, N = 1024
	
	DDRB = 0xFF; //PORTB output
	DDRD = 0xFF; //PORTD output

	int incRed = 1;	// variable to modify red duty cycle
	int incGreen = 1;	//variable to modify green duty cycle
	int incBlue = 1;	// variable to modify blue duty cycle
	
	int countRed = 0; //initialize index for Red Prescalar Array
	int countGreen = 0;//initialize index for Green Prescalar Array
	int countBlue = 0;	//initialize index for Blue Prescalar Array
	
	red = green = blue = 0; //initializing the variables
	
	while (1)
	{
		OCR0A = green;	// green
		OCR1A = blue;	// blue
		OCR2A = red;	// red
		_delay_ms(4); //use AVR studio library delay
		if(incGreen)	// if true, increase PWM
		{
			green++; // increase PWM top
			TCCR0B = arrG[countGreen]; // configure with different prescalers each time
			if(green==200)
				incGreen=0;	// once top is reached set variable to down count
				
			if(countGreen<5 && green==70) // after the top is at 70, increment prescaler array index
				countGreen++;
		}else // otherwise decrease PWM top
		{
			green--;
			if(green==0)
				incGreen=1; // once bottom is reached set variable to count up
			if(countGreen >= 5) // after the prescaler array has been parsed once, reset to original prescaler
			{
				TCCR0B = 0x04;
				countGreen = 0;
			}
		}
		//==================
		_delay_ms(2);
		if(incBlue)	// if true, increase PWM
		{
			blue++; // increase PWM top
			TCCR1B = arrB[countBlue]; // configure with different prescalers each time
			if(blue==125)
				incBlue=0; // once top is reached set variable to down count
			if(countBlue<5 && blue==75) // after the top is at 75, increment prescaler array index
				countBlue++;
		}else // otherwise decrease PWM top
		{
			blue--;
			if(blue==0)
				incBlue=1; // once bottom is reached set variable to count up
			if(countBlue >= 5) // after the prescaler array has been parsed once, reset to original prescaler
			{
				TCCR1B = 0x01;
				countBlue = 0;
			}
		}
		//===========================
		_delay_ms(2);
		if(incRed)	// if true, increase PWM
		{
			red++; // increase PWM top
			TCCR2B = arrR[countRed]; // configure with different prescalers each time
			if(red==255)
				incRed=0; // once top is reached set variable to down count
			if(countRed<5 && red==100) // after the top is at 100, increment prescaler array index
				countRed++;
		}else // otherwise decrease PWM top
		{
			red--;
			if(red==0)
				incRed=1; // once bottom is reached set variable to count up
			if(countRed >= 5)
			{
				TCCR2B = 0x05;
				countRed = 0; // after the prescaler array has been parsed once, reset to original prescaler
			}
		}
	}
	return 0;
}